<template>
  <div>
    <el-card shadow="always" :body-style="{ padding: '20px' }">
      <template #header>
        <el-button
          type="primary"
          size="default"
          icon="ele-Plus"
          @click="addDialog"
          >添加</el-button
        >
      </template>
      <!-- card body -->
      <!-- 
      el-tabel属性:
        data:当前表格对应的数组

      el-table-column属性
        type:index:代表当前列是序号
        label:代表当前列的表头
        prop:值是一个标识而已,让当前组件去数组数据中每一条找到对应的值组成一列

     -->
      <el-table border stripe :data="trademarkList" v-loading="tabelLoading">
        <!-- table-column 作用域插槽提供的row对象是当前列所在行的整个数据,$index是当前列所在行的下标-->
        <el-table-column type="index" width="120" label="序号" />
        <el-table-column label="品牌名称" prop="tmName"> </el-table-column>
        <el-table-column label="品牌logo">
          <template v-slot="{ row }">
            <img :src="row.logoUrl" width="100" alt="" />
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ row }">
            <el-button
              type="warning"
              size="small"
              icon="ele-Edit"
              @click="update(row)"
              >修改</el-button
            >
            <!-- 
            el-popconfirm组件:气泡确认框
              - title:确认框的内容
              - confirmButtonText:确认按钮的文字
              - cancelButtonText:取消按钮的文字
              - confirmButtonType:确认按钮的按钮类型
              - cancelButtonType:取消按钮的按钮类型
              - icon:图标
              - iconColor:图标颜色
              - @confirm:确认的事件
           -->
            <el-popconfirm
              confirm-button-text="确认"
              cancel-button-text="取消"
              icon="ele-Delete"
              icon-color="#626AEF"
              title="是否确认删除该品牌?"
              @confirm="deleteTrademark(row.id)"
            >
              <template #reference>
                <el-button type="danger" size="small" icon="ele-Delete"
                  >删除</el-button
                >
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

      <!-- 
      current-page:当前页
      page-size:每页数量
      page-sizes:可以选择每页展示的条数的选项
      total:数据总数量
      layout:布局排序
     -->
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[3, 5, 7, 9]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="totalNum"
        :style="{ marginTop: '25px' }"
      />
    </el-card>

    <!-- 
    dialog组件属性:
      v-model:是否显示 Dialog
      width:Dialog的宽度
      before-close:关闭前的回调函数
    dialog插槽:
      1.具名插槽header:弹窗的标题
      2.具名插槽footer:按钮区内容
      3. 默认插槽:Dialog 的内容

   -->
    <el-dialog v-model="dialogVisible" width="45%">
      <template #header> 添加品牌 </template>

      <!-- 
      el-form组件的属性:
        label-width:每一个表单都是label字符和表单元素组成,可以统一控制label的宽度
        :inline:是否是行内表单
        size:表单尺寸

      el-form-item组件:
        每一个表单元素必须配置一个el-form-item组件
        label属性：就是当前表单的label值
     -->
      <el-form
        label-width="120px"
        size="default"
        :model="tmInfo"
        :rules="rules"
        ref="ruleFormRef"
      >
        <el-form-item label="品牌名称" prop="tmName">
          <el-input v-model="tmInfo.tmName" />
        </el-form-item>
        <el-form-item label="品牌logo" prop="logoUrl">
          <!-- 
          单独文件上传的组件el-upload组件
            - action：图片上传的地址
            - show-file-list：是否展示已经上传的图片列表
            - on-success:文件上传成功钩子函数 (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => void
            - before-upload:上传文件之前的钩子 (rawFile: UploadRawFile) => Awaitable<void | undefined | null | boolean | File | Blob>
         -->
          <el-upload
            class="avatar-uploader"
            :action="`${baseUrl}/admin/product/upload`"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img v-if="tmInfo.logoUrl" :src="tmInfo.logoUrl" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon">
              <ele-Plus />
            </el-icon>
          </el-upload>
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="addOrUpdateTrademark">
            确认
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts">
  import { defineComponent } from "vue"

  export default defineComponent({
    name: "Trademark",
  })
</script>

<script setup lang="ts">
  import { onMounted, reactive, ref, watch } from "vue"
  import {
    reqTrademarkList,
    reqAddTrademark,
    reqUpdateTrademark,
    reqDeleteTrademark,
  } from "@/api/trademark"
  import type { trademarkListType, trademarkItemType } from "@/api/trademark"
  import type { FormRules, UploadProps } from "element-plus"
  import { ElMessage } from "element-plus"

  //定义一个发送请求时的loading状态，默认false
  const tabelLoading = ref(false)

  //页码逻辑
  const currentPage = ref(1) //当前页
  const pageSize = ref(3) //每页数量
  const totalNum = ref(0) //数据总数量

  //品牌列表数据
  const trademarkList = ref<trademarkListType>([])

  //封装一个请求分页列表的方法(方便未来数据改变的时候再次请求)
  const getTrademarkList = async () => {
    //发起数据请求时开启loading
    tabelLoading.value = true

    //发送品牌数据列表的请求
    const res = await reqTrademarkList(currentPage.value, pageSize.value)
    //赋值操作
    trademarkList.value = res.records
    totalNum.value = res.total

    //请求结束后立即关闭loading
    tabelLoading.value = false
  }

  //初始化发送品牌分页列表请求
  onMounted(() => {
    getTrademarkList()
  })

  //监听当前页和每页条数的变化，一旦发生改变就重新发起请求，获取最新数据
  watch([currentPage, pageSize], () => {
    getTrademarkList()
  })

  //定义弹窗的是否展示的状态
  const dialogVisible = ref(false)

  //收集公共请求前缀，从环境变量中读取
  const baseUrl = import.meta.env.VITE_API_URL

  // const tmName = ref("")
  // const imageUrl = ref("")
  //定义一个品牌名称和品牌图片的对象，方便后续使用
  const tmInfo = ref<trademarkItemType>({
    tmName: "",
    logoUrl: "",
  })

  //创建一个保存form组件的数据
  const ruleFormRef = ref()

  //自定义校验规则
  const checkTmname = (rule: any, value: any, callback: any) => {
    return value.length >= 2 && value.length <= 10
  }

  //弹出框的表单校验规则
  const rules = reactive<FormRules>({
    tmName: [
      { required: true, message: "品牌名称不能为空", trigger: "blur" },
      //在规则中使用validator来使用自定义规则函数
      {
        validator: checkTmname,
        message: "品牌名称长度为2-10个字符",
        trigger: "blur",
      },
    ],
    logoUrl: [{ required: true, message: "品牌图片不能为空", trigger: "blur" }],
  })

  //点击添加按钮打开弹窗的事件回调函数
  const addDialog = async () => {
    //打开弹窗
    dialogVisible.value = true
    try {
      //每次打开弹窗时应清空之前的校验规则残留（异步）
      await ruleFormRef.value.clearValidate()

      //重置表单数据
      tmInfo.value.tmName = ""
      tmInfo.value.logoUrl = ""
    } catch (error) {
      ElMessage.error("清空上一次的校验规则失败")
    }
  }

  //上传图片的事件回调函数--文件上传成功的钩子函数
  const handleAvatarSuccess: UploadProps["onSuccess"] = (response) => {
    //上传成功以后，会响应数据response response中有一个data就是上传后的图片地址
    tmInfo.value.logoUrl = response.data
  }

  //上传图片的事件回调函数-文件上传之前的钩子函数
  const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
    //判断上传的文件的类型和大小
    if (rawFile.type !== "image/jpeg") {
      ElMessage.error("只能上传JPG格式的图片!")
      return false
    } else if (rawFile.size / 1024 / 1024 > 2) {
      ElMessage.error("上传的图片大小不能超过2M!")
      return false
    }
    return true
  }

  //当前的事件可能发送的新增,也可能发送的修改,需要通过tmInfo的id来确认（新增没有id，修改时才有id）
  const addOrUpdateTrademark = async () => {
    // const tmInfo: trademarkItemType = {
    //   tmName: tmName.value,
    //   logoUrl: imageUrl.value
    // }

    //表单的整体校验规则
    try {
      await ruleFormRef.value.validate()
      if (tmInfo.value.id) {
        //初始化修改品牌的请求
        await reqUpdateTrademark(tmInfo.value)
        //弹窗提示成功信息
        ElMessage.success("修改品牌成功")
      } else {
        //初始化新增品牌的请求
        await reqAddTrademark(tmInfo.value)
        //弹窗提示成功信息
        ElMessage.success("添加品牌成功")
      }

      //关闭弹窗
      dialogVisible.value = false
      //获取最新的品牌列表数据
      getTrademarkList()
    } catch (error) {
      ElMessage.error("输入格式有误！")
    }
  }

  //修改品牌的按钮事件回调函数
  const update = (row: trademarkItemType) => {
    //获取当前修改按钮所在的这条数据也就是row 将其赋值给弹窗内控制数据的对象 tmInfo
    //因为tmInfo绑定的是弹窗内的数据，所以一旦赋值并打开弹窗，就会回填数据
    dialogVisible.value = true
    //点击修改按钮后清空之前的校验规则残留
    ruleFormRef.value.clearValidate()

    //如果把row直接赋值给tmInfo,tmInfo是双向绑定输入框的,只要输入框内容改变,则row的数据也会改变,品牌列表的内容也会改变
    //所以我们要经过拷贝把row的值赋值给tmInfo(当前数据结构简单,只需要浅拷贝即可)
    tmInfo.value = { ...row }
  }

  //点击删除按钮的事件回调函数
  const deleteTrademark = async (id: number) => {
    //发送删除请求
    await reqDeleteTrademark(id)
    //弹窗提示成功信息
    ElMessage.success("品牌删除成功！")
    //获取最新的品牌列表数据
    getTrademarkList()
  }
</script>

<style scoped lang="scss">
  .avatar-uploader .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
</style>

<style lang="scss">
  .avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
  }

  .avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
  }

  .el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
  }
</style>
